/**
 * @file wall.cpp
 * @brief Wall class methods implementation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * @author VestniK (Sergey N.Vidyuk) sir.vestnik@gmail.com
 * @date 10 Oct 2008
 */
#include "wall.h"

#include <cstdlib>

#include <QtCore/QDateTime>

#include "defaults.h"
#include "tileset.h"

using namespace mjn;

/**
 *
 */
Wall::Wall() {
}

/**
 *
 */
Wall::~Wall() {
}

/**
 *
 */
void Wall::buildWall(const TileSet& tileset) {
   WallTiles.clear();
   DeadEndTiles.clear();
   QList<TileID> tiles;
   for (TileID t = 0; t < tileset.getTilesCount(); t++) {
      tiles.append(t);
   }
   // Getting random tiles from tmp list to WallTiles list
   srand( QDateTime::currentDateTime().toTime_t() );
   while ( ! tiles.isEmpty() ) {
      int RndIndx = rand() % tiles.size();
      WallTiles.append( tiles.takeAt(RndIndx) );
   }
   // Filling dead end
   DeadEndTiles.append( WallTiles.takeFirst() );
   DeadEndTiles.append( WallTiles.takeFirst() );
}

/**
 * Takes a tile from the wall and returns copy of it. If the wall contain 14
 * (or less) tiles 0 pointer is returned.
 */
TileID Wall::takeTile() throw(WallEmptyException) {
   if ( WallTiles.isEmpty() ) {
      throw( WallEmptyException() );
   }
   if ( WallTiles.size() <= MINIMUM_WALL_SIZE ) {
      return -1;
   }
   return WallTiles.takeLast();
}

/**
 * Takes tile from dead end and returns copy of it. If dead end become empty
 * two tiles are taken from the beggining of the wall (dead coner of the wall)
 * to refill dead end.
 */
TileID Wall::takeFromDeadEnd() throw(DeadEndEmptyException) {
   if ( DeadEndTiles.isEmpty() ) {
      throw( DeadEndEmptyException() );
   }
   TileID t = DeadEndTiles.takeLast();
   // Refill dead end if it bocome empty
   if ( DeadEndTiles.isEmpty() ) {
      for (int i = 0; i < DEAD_END_SIZE; i++) {
         if ( WallTiles.isEmpty() ) {
            return t;
         }
         DeadEndTiles.append( WallTiles.takeFirst() );
      }
   }
   return t;
}

/**
 * When the wall contain only 14 tiles (or less) round decided to be failed and
 * should be stopped.
 *
 * @return @b true if the number of tiles in the wall is 14 or less.
 */
bool Wall::isOver() const {
   if ( WallTiles.size() <= MINIMUM_WALL_SIZE ) {
      return true;
   }
   return false;
}
